package com.excel.validators.core.decorative;

import java.util.List;

import com.excel.validators.core.exception.TerminaledException;

/**
 * 模型层统处理
 * @author wangxiaoliang10
 */
@SuppressWarnings({"rawtypes","unchecked"})
public abstract class AbstractSheet extends DynamicModel {
	
	/*
	 * 命名空间，处理不同的输入输出模型
	 */
	private String namespace;
	
	private boolean hasError = false;
	
	/*
	 * 每行excel中各单元格的验证器
	 */
	private List<CompositeValue> composite;

	/**
	 * 获取所有单元格的验证器
	 * @return
	 */
	protected List<CompositeValue> getComposites() {
		if (composite == null) {
				composite = createCompositeValues();
				if (logger.isTraceEnabled()) {
						traceValue(composite);
				}
		}
		return composite;
	}
	
	/**
	 * debug function
	 * @param compositeValues
	 */
	private void traceValue(List<CompositeValue> values) {
			int rowIndex = 1;
			for (CompositeValue composite : values) {
					logger.trace("excel line number:" + rowIndex);
					for (FieldValue fieldValue : composite) {
							logger.trace("The audit cell is: " + fieldValue.getFieldName() + ""
									+ " and value is :" + fieldValue.getOldValue());
					}
			}
	}

	/**
	 * 批量生成检查器，用于随后的统一参数检查
	 * @return
	 */
	protected abstract List<CompositeValue> createCompositeValues();

	/**
	 * 校验入口
	 * @return
	 */
	public void validate() {
			// TODO get validator by namespace
			Validator strategy = getValidator();
			if (strategy != null) {
					int process = 0;
					List<Object> modelvalues = getModelObject();
					for (Object modelvalue : modelvalues) {
							try {
									strategy.dedicate(composite.get(process));
									// TODO check values basic on line
									strategy.inspect(modelvalue);
							} catch (Exception e) {
									if (e instanceof TerminaledException) {
											hasError = true;
											break;
									} else {
											logger.error("",e);
									}
							}
							process++;
					}
			}
	}

	public abstract List<Object> getModelObject();
	
	/**
	 * check sheet error
	 * @return
	 */
	public boolean hasError() {
			if (!hasError) {
					for (CompositeValue compositeValue : composite) {
							if (compositeValue.hasError()) {
									hasError = true;
									break;
							}
					}
			}
			return hasError;
	}

	
	
	@Override
	public String getNamespace() {
			return namespace;
	}
	
	@Override
	public void setNamespace(String namespace) {
			this.namespace = namespace;
	}
	
}
